#!/bin/bash

mk_fhs() {
    mkdir -pv {bin,boot,dev,etc/{opt,sysconfig},home,lib/firmware,mnt,opt,proc}
    mkdir -pv {media/{floppy,cdrom},sbin,srv,sys,var/{,run}}
    #install -dv -m 0750 root
    #install -dv -m 1777 tmp var/tmp
    mkdir -pv usr/{,local/}{bin,include,lib,sbin,src}
    mkdir -pv usr/{,local/}share/{color,dict,doc,info,locale,man}
    mkdir -v  usr/{,local/}share/{misc,terminfo,zoneinfo}
    mkdir -v  usr/libexec
    mkdir -pv usr/{,local/}share/man/man{1..8}
    mkdir -v  var/{log,mail,spool}
    ln -sv run var/run
    ln -sv run/lock var/lock
    mkdir -pv var/{opt,cache,lib/{color,misc,locate},local}
}

mk_musl() {
    tar -xvf ../dump/"$MUSL_HASH".tar > /dev/null
    cd musl
    # --enable-wrapper=gcc
    # makes it install musl-gcc on musl based systems, even though you don't need it it helps portability 
    ./configure --enable-wrapper=gcc --prefix=${ROOT} --exec-prefix=${ROOT} --syslibdir=${ROOT}/lib --disable-shared || exit -1
    make || exit -1
    make install || exit -1
}

mk_suck() {
    tar -xvf ../dump/"$2".tar > /dev/null
    cd "$1"
    # NOTE: CFLAGS had to be passed for sbase/ubase
    # -D_XOPEN_SOURCE=600 added for sinit to build
    make PREFIX="${ROOT}" CC="${ROOT}/bin/musl-gcc -static" CFLAGS="-std=c99 -Wall -D_BSD_SOURCE" || exit -1
    make install PREFIX=${ROOT} CC=${ROOT}/bin/musl-gcc || exit -1
}

mk_mksh() {
    tar -xvf ../dump/"$MKSH_HASH".tar > /dev/null
    cd mksh
    CC="${ROOT}/bin/musl-gcc -static" sh Build.sh || exit -1
    cp mksh ${ROOT}/bin/
}

mk_modtools() {
    tar -xvf ../dump/"$MODTOOLS_HASH".tar > /dev/null
    cd module-init-tools-3.15
    CC="${ROOT}/bin/musl-gcc -static" ./configure
    CC="${ROOT}/bin/musl-gcc -static" make insmod lsmod rmmod depmod modprobe || exit -1
    cp build/insmod ${ROOT}/bin/
    cp build/lsmod ${ROOT}/bin/
    cp build/rmmod ${ROOT}/bin/
    cp build/depmod ${ROOT}/bin/
    cp build/modprobe ${ROOT}/bin/
}

mk_fbvis() {
    tar -xvf ../dump/"$FBVIS_HASH".tar > /dev/null
    cd fbvis
    make CC="${ROOT}/bin/musl-gcc -static -I/usr/include/" || exit -1
    cp fbvis ${ROOT}/bin/
}

mk_neatcc() {
    . ../repack/pkgs/neatcc.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    make CC="${ROOT}/bin/musl-gcc -static" || exit -1
    cp neatcc ${ROOT}/bin/
    cp ncc ${ROOT}/bin/
}

mk_neatld() {
    . ../repack/pkgs/ld.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    make CC="${ROOT}/bin/musl-gcc -static" || exit -1
    cp nld ${ROOT}/bin/
}

mk_binutils() {
    . ../repack/pkgs/binutils-2.26.51.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    ./configure --prefix=${ROOT} || exit -1
    make CC="${ROOT}/bin/musl-gcc -static" || exit -1
    make install || exit -1
}

mk_pcc() {
    . ../repack/pkgs/pcc-20160411.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    ./configure --prefix=${ROOT} || exit -1
    make CC="${ROOT}/bin/musl-gcc -static" || exit -1
    make install || exit -1
}

mk_ncurses() {
    . ../repack/pkgs/ncurses-6.0.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    ./configure --prefix=${ROOT} --without-cxx || exit -1
    make CC="${ROOT}/bin/musl-gcc -static" || exit -1
    make install || exit -1
}

mk_gettext() {
    . ../repack/pkgs/gettext-0.19.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    ./configure --prefix=${ROOT} CXX="g++" || exit -1
    make CC="${ROOT}/bin/musl-gcc -static" || exit -1
    make install || exit -1
}

mk_make() {
    . ../repack/pkgs/make-4.1.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    ./configure --prefix=${ROOT} || exit -1
    make CC="${ROOT}/bin/musl-gcc -static" || exit -1
    make install || exit -1
}

mk_gmp() {
    . ../repack/pkgs/gmp-6.1.0.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    ./configure --prefix=${ROOT} --disable-shared || exit -1
    make CC="${ROOT}/bin/musl-gcc" || exit -1
    make install || exit -1
}

mk_mpfr() {
    . ../repack/pkgs/mpfr-3.1.4.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    ./configure --prefix=${ROOT} \
                --disable-shared \
                --with-gmp-include=${ROOT}/include \
                --with-gmp-lib=${ROOT}/lib \
        || exit -1
    make CC="${ROOT}/bin/musl-gcc" || exit -1
    make install || exit -1
  #     --with-gmp-include=DIR  GMP include directory
  # --with-gmp-lib=DIR      GMP lib directory
  # --with-gmp=DIR          GMP install directory
  # --with-gmp-build=DIR    GMP build directory (please read INSTALL file)
}

mk_mpc() {
    . ../repack/pkgs/mpc-1.0.2.sh
    tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    ./configure --prefix=${ROOT} \
                --disable-shared \
                --with-gmp-include=${ROOT}/include \
                --with-gmp-lib=${ROOT}/lib \
        || exit -1
    make CC="${ROOT}/bin/musl-gcc" || exit -1
    make install || exit -1
  #     --with-gmp-include=DIR  GMP include directory
  # --with-gmp-lib=DIR      GMP lib directory
  # --with-gmp=DIR          GMP install directory
  # --with-gmp-build=DIR    GMP build directory (please read INSTALL file)
}

mk_gcc() {
    . ../repack/pkgs/gcc-5.3.0.sh
    # can comment the following line to speed up dev
    #tar -xvf ../repack/dump/"$PACK_HASH".tar > /dev/null
    cd "$PACK_NAME"
    ./configure --prefix=${ROOT} --with-gmp=${ROOT} --with-mpfr=${ROOT} --with-mpc=${ROOT} \
    --with-sysroot=${ROOT}                            \
    --disable-nls                                  \
    --disable-shared                               \
    --disable-multilib                             \
    --disable-decimal-float                        \
    --disable-threads                              \
    --disable-libatomic                            \
    --disable-libgomp                              \
    --disable-libquadmath                          \
    --disable-libssp                               \
    --disable-libvtv                               \
    --disable-libstdcxx                            \
    --enable-languages=c,c++ \
    || exit -1
    make CC="${ROOT}/bin/musl-gcc -static" || exit -1
    make install || exit -1
}

# mk_fbset() {
#     tar -xvf ../dump/"$FBSET_HASH".tar > /dev/null
#     cd fbset-2.1
#     make CC="${ROOT}/bin/musl-gcc -static" || exit -1
#     make install || exit -1
# }

mk_conf() {
    cat > etc/fstab << "EOF"
/dev/sda       /            ext4     defaults            1     1
EOF

    cat > bin/rc.init << "EOF"
#!/bin/mksh

echo -------------------------
echo - WELCOME TO THE MATRIX -
echo -------------------------

mountpoint -q /proc || mount -t proc proc /proc -o nosuid,noexec,nodev
mountpoint -q /sys || mount -t sysfs sys /sys -o nosuid,noexec,nodev
#mountpoint -q /var/run || mount -t tmpfs run /run -o mode=0775,nosuid,nodev
mountpoint -q /dev || mount -t devtmpfs dev /dev -o mode=0755,nosuid

mkdir /dev/pts /dev/shm

mountpoint -q /dev/pts || mount -t devpts devpts /dev/pts -o mode=0620,gid=5,nosuid,noexec
mountpoint -q /dev/shm || mount -t tmpfs shm /dev/shm -o mode=1777,nosuid,nodev

mount -t tmpfs tmpfs /tmp -o mode=1777,nosuid,nodev

mount -a
mount -o remount,rw /

echo -------------------------

fbvis /boot/trinity.png
sleep 5
killall fbvis

mksh
EOF
    
    chmod +x bin/rc.init
    
cat > etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/mksh
bin:x:1:1:bin:/dev/null:/bin/false
daemon:x:6:6:Daemon User:/dev/null:/bin/false
nobody:x:99:99:Unprivileged User:/dev/null:/bin/false
EOF

cat > etc/group << "EOF"
root:x:0:
bin:x:1:daemon
sys:x:2:
kmem:x:3:
tape:x:4:
tty:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
usb:x:14:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
systemd-journal:x:23:
input:x:24:
mail:x:34:
nogroup:x:99:
users:x:999:
EOF
}

. ./pkg.sh

export BASE=`pwd`

mkdir -p root
export ROOT=`pwd`/root

mkdir -p src

cd "$ROOT"
mk_fhs

cp "$BASE"/trinity.png "$ROOT"/boot/ || exit -1

cd "$BASE"/src
mk_musl

cd "$BASE"/src
mk_suck sbase "$SBASE_HASH"

cd "$BASE"/src
mk_suck ubase "$UBASE_HASH"

cd "$BASE"/src
mk_suck sinit "$SINIT_HASH"
cp "$ROOT"/bin/sinit "$ROOT"/sbin/init

#cd "$BASE"/src
#mk_suck smdev "$SMDEV_HASH"

#cd "$BASE"/src
#mk_mksh

#cd "$BASE"/src
#mk_modtools

cd "$BASE"/src
mk_fbvis

cd "$BASE"/src
mk_neatcc

cd "$BASE"/src
mk_neatld

cd "$BASE"/src
mk_binutils

cd "$BASE"/src
mk_pcc

cd "$ROOT"
mk_conf
